package com.yss.sofa.report.engine.json;

import java.io.IOException;

import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.DeserializationContext;
import org.codehaus.jackson.map.JsonDeserializer;
import org.codehaus.jackson.node.BooleanNode;
import org.codehaus.jackson.node.IntNode;

import com.yss.sofa.report.engine.Const;
import com.yss.sofa.report.engine.cell.visible.form.CheckBoxFormCell;
import com.yss.sofa.report.engine.cell.visible.form.CustomFormCell;
import com.yss.sofa.report.engine.cell.visible.form.DataSetListFormCell;
import com.yss.sofa.report.engine.cell.visible.form.DataSetTreeFormCell;
import com.yss.sofa.report.engine.cell.visible.form.DateFormCell;
import com.yss.sofa.report.engine.cell.visible.form.FormCell;
import com.yss.sofa.report.engine.cell.visible.form.LazyListFormCell;
import com.yss.sofa.report.engine.cell.visible.form.LazyTreeFormCell;
import com.yss.sofa.report.engine.cell.visible.form.NumberFormCell;
import com.yss.sofa.report.engine.cell.visible.form.PasswordFormCell;
import com.yss.sofa.report.engine.cell.visible.form.TextFormCell;
import com.yss.sofa.report.engine.cell.visible.form.UrlListFormCell;
import com.yss.sofa.report.engine.cell.visible.form.UrlTreeFormCell;
import com.yss.sofa.report.engine.cell.visible.form.UrlTreeSelectFormCell;

public class FormCellDeserializer extends JsonDeserializer<FormCell>{
	public FormCell deserialize(JsonParser jp, DeserializationContext ctxt)	throws IOException, JsonProcessingException {
		FormCell result=null;
		JsonNode node = jp.getCodec().readTree(jp); 
		int inputType=(Integer) ((IntNode) node.get("inputType")).getNumberValue();
		String value=node.has("value")?node.get("value").asText():null;
		String raw=node.has("raw")?node.get("raw").asText():null;
		String code=node.get("code").asText();
		boolean allowBlank=node.has("allowBlank")?((BooleanNode) node.get("allowBlank")).getBooleanValue():false;
		boolean disabled=node.has("disabled")?((BooleanNode) node.get("disabled")).getBooleanValue():false;
		boolean readOnly=node.has("readOnly")?((BooleanNode) node.get("readOnly")).getBooleanValue():false;
		switch (inputType) {
		case Const.FORM_INPUT_TYPE_CUSTOM:{
			CustomFormCell custom=new CustomFormCell();
			custom.setInputType(inputType);
			custom.setValue(value);
			custom.setRaw(raw);
			custom.setCode(code);
			custom.setAllowBlank(allowBlank);
			custom.setDisabled(disabled);
			custom.setReadOnly(readOnly);
			String template=node.get("template").asText();
			String extra=node.has("extra")?node.get("extra").asText():null;
			custom.setTemplate(template);
			custom.setExtra(extra);
			result=custom;
			break;
		}
		case Const.FORM_INPUT_TYPE_TEXT:{
			TextFormCell text=new TextFormCell();
			text.setInputType(inputType);
			text.setValue(value);
			text.setRaw(raw);
			text.setCode(code);
			text.setAllowBlank(allowBlank);
			text.setDisabled(disabled);
			text.setReadOnly(readOnly);
			int minLength=node.has("minLength")?((Integer) ((IntNode) node.get("minLength")).getNumberValue()):0;
			int maxLength=node.has("maxLength")?((Integer) ((IntNode) node.get("maxLength")).getNumberValue()):Integer.MAX_VALUE;
			text.setMinLength(minLength);
			text.setMaxLength(maxLength);
			result=text;
			break;
		}
		case Const.FORM_INPUT_TYPE_DATE:{
			DateFormCell date=new DateFormCell();
			date.setInputType(inputType);
			date.setValue(value);
			date.setRaw(raw);
			date.setCode(code);
			date.setAllowBlank(allowBlank);
			date.setDisabled(disabled);
			date.setReadOnly(readOnly);
			String max=node.has("max")?node.get("max").asText():"2099-12-31";
			String min=node.has("min")?node.get("min").asText():"1900-01-01";
			date.setMax(max);
			date.setMin(min);
			result=date;
			break;
		}	
		case Const.FORM_INPUT_TYPE_NUMBER:{
			NumberFormCell number=new NumberFormCell();
			number.setInputType(inputType);
			number.setValue(value);
			number.setRaw(raw);
			number.setCode(code);
			number.setAllowBlank(allowBlank);
			number.setDisabled(disabled);
			number.setReadOnly(readOnly);
			String max=node.has("max")?node.get("max").asText():Double.toString(1000000000000d);
			String min=node.has("min")?node.get("min").asText():Double.toString(-1000000000000d);
			String precision=node.has("precision")?node.get("precision").asText():"0";
			number.setMax(max);
			number.setMin(min);
			number.setPrecision(precision);
			result=number;
			break;
		}	
		case Const.FORM_INPUT_TYPE_URL_LIST:{
			UrlListFormCell urllist=new UrlListFormCell();
			urllist.setInputType(inputType);
			urllist.setValue(value);
			urllist.setRaw(raw);
			urllist.setCode(code);
			urllist.setAllowBlank(allowBlank);
			urllist.setDisabled(disabled);
			urllist.setReadOnly(readOnly);
			boolean multi=node.has("multi")?((BooleanNode) node.get("multi")).getBooleanValue():false;
			String url=node.get("url").asText();
			String displayField=node.has("displayField")?node.get("displayField").asText():"name";
			String valueField=node.has("valueField")?node.get("valueField").asText():"id";
			String mode=node.has("mode")?node.get("mode").asText():"remote";
			int search=node.has("search")?((Integer) ((IntNode) node.get("search")).getNumberValue()):4;
			String query=node.has("query")?node.get("query").asText():Const.NONE;
			urllist.setMulti(multi);
			urllist.setUrl(url);
			urllist.setDisplayField(displayField);
			urllist.setValueField(valueField);
			urllist.setMode(mode);
			urllist.setSearch(search);
			urllist.setQuery(query);
			result=urllist;
			break;
		}
		case Const.FORM_INPUT_TYPE_URL_TREE:{
			UrlTreeFormCell urltree=new UrlTreeFormCell();
			urltree.setInputType(inputType);
			urltree.setValue(value);
			urltree.setRaw(raw);
			urltree.setCode(code);
			urltree.setAllowBlank(allowBlank);
			urltree.setDisabled(disabled);
			urltree.setReadOnly(readOnly);
			boolean leaf=node.has("leaf")?((BooleanNode) node.get("leaf")).getBooleanValue():true;
			boolean multi=node.has("multi")?((BooleanNode) node.get("multi")).getBooleanValue():false;
			String url=node.get("url").asText();
			String displayField=node.has("displayField")?node.get("displayField").asText():"name";
			String valueField=node.has("valueField")?node.get("valueField").asText():"id";
			String mode=node.has("mode")?node.get("mode").asText():"remote";
			int search=node.has("search")?((Integer) ((IntNode) node.get("search")).getNumberValue()):4;
			String query=node.has("query")?node.get("query").asText():Const.NONE;
			urltree.setLeaf(leaf);
			urltree.setMulti(multi);
			urltree.setUrl(url);
			urltree.setDisplayField(displayField);
			urltree.setValueField(valueField);
			urltree.setMode(mode);
			urltree.setSearch(search);
			urltree.setQuery(query);
			result=urltree;
			break;
		}
		case Const.FORM_INPUT_TYPE_URL_TREE_SELECT:{
			UrlTreeSelectFormCell urlTreeSelectFormCell=new UrlTreeSelectFormCell();
			urlTreeSelectFormCell.setInputType(inputType);
			urlTreeSelectFormCell.setValue(value);
			urlTreeSelectFormCell.setRaw(raw);
			urlTreeSelectFormCell.setCode(code);
			urlTreeSelectFormCell.setAllowBlank(allowBlank);
			urlTreeSelectFormCell.setDisabled(disabled);
			urlTreeSelectFormCell.setReadOnly(readOnly);
			boolean leaf=node.has("leaf")?((BooleanNode) node.get("leaf")).getBooleanValue():true;
			boolean multi=node.has("multi")?((BooleanNode) node.get("multi")).getBooleanValue():false;
			String url=node.get("url").asText();
			String sofaUrl=node.has("sofaUrl")?node.get("sofaUrl").asText():"";
			String displayField=node.has("displayField")?node.get("displayField").asText():"name";
			//String valueField=node.has("valueField")?node.get("valueField").asText():"id";
			String mode=node.has("mode")?node.get("mode").asText():"remote";
			int search=node.has("search")?((Integer) ((IntNode) node.get("search")).getNumberValue()):4;
			String query=node.has("query")?node.get("query").asText():Const.NONE;
			
			int limitCount=node.has("limitCount")?((Integer) ((IntNode) node.get("limitCount")).getNumberValue()):999999;
			String igronSelectField=node.has("igronSelectField")?node.get("igronSelectField").asText():"";
			int delay=node.has("delay")?((Integer) ((IntNode) node.get("delay")).getNumberValue()):500;
			String blankText=node.has("blankText")?node.get("blankText").asText():"";
			boolean expandAll=node.has("expandAll")?((BooleanNode) node.get("expandAll")).getBooleanValue():true;
			boolean canInput=node.has("canInput")?((BooleanNode) node.get("canInput")).getBooleanValue():false;
			String placeholder=node.has("placeholder")?node.get("placeholder").asText():"";
			String splitQuery=node.has("splitQuery")?node.get("splitQuery").asText():"";
			String validator=node.has("validator")?node.get("validator").asText():"";
			
			urlTreeSelectFormCell.setLeaf(leaf);
			urlTreeSelectFormCell.setMulti(multi);
			urlTreeSelectFormCell.setUrl(url);
			urlTreeSelectFormCell.setSofaUrl(sofaUrl);
			urlTreeSelectFormCell.setDisplayField(displayField);
			//urlTreeSelectFormCell.setValueField(valueField);
			urlTreeSelectFormCell.setMode(mode);
			urlTreeSelectFormCell.setSearch(search);
			urlTreeSelectFormCell.setQuery(query);
			
			urlTreeSelectFormCell.setLimitCount(limitCount);
			urlTreeSelectFormCell.setIgronSelectField(igronSelectField);
			urlTreeSelectFormCell.setDelay(delay);
			urlTreeSelectFormCell.setBlankText(blankText);
			urlTreeSelectFormCell.setExpandAll(expandAll);
			urlTreeSelectFormCell.setCanInput(canInput);
			urlTreeSelectFormCell.setPlaceholder(placeholder);
			urlTreeSelectFormCell.setSplitQuery(splitQuery);
			urlTreeSelectFormCell.setValidator(validator);
			result=urlTreeSelectFormCell;
			break;
		}
		case Const.FORM_INPUT_TYPE_DATASET_LIST:{
			DataSetListFormCell dslist=new DataSetListFormCell();
			dslist.setInputType(inputType);
			dslist.setValue(value);
			dslist.setRaw(raw);
			dslist.setCode(code);
			dslist.setAllowBlank(allowBlank);
			dslist.setDisabled(disabled);
			dslist.setReadOnly(readOnly);
			boolean multi=node.has("multi")?((BooleanNode) node.get("multi")).getBooleanValue():false;
			String dataset=node.get("dataset").asText();
			int search=node.has("search")?((Integer) ((IntNode) node.get("search")).getNumberValue()):4;
			dslist.setMulti(multi);
			dslist.setDataset(dataset);
			dslist.setSearch(search);
			result=dslist;
			break;
		}
		case Const.FORM_INPUT_TYPE_DATASET_TREE:{
			DataSetTreeFormCell dstree=new DataSetTreeFormCell();
			dstree.setInputType(inputType);
			dstree.setValue(value);
			dstree.setRaw(raw);
			dstree.setCode(code);
			dstree.setAllowBlank(allowBlank);
			dstree.setDisabled(disabled);
			dstree.setReadOnly(readOnly);
			boolean leaf=node.has("leaf")?((BooleanNode) node.get("leaf")).getBooleanValue():true;
			boolean multi=node.has("multi")?((BooleanNode) node.get("multi")).getBooleanValue():false;
			String dataset=node.get("dataset").asText();
			int search=node.has("search")?((Integer) ((IntNode) node.get("search")).getNumberValue()):4;
			dstree.setLeaf(leaf);
			dstree.setMulti(multi);
			dstree.setDataset(dataset);
			dstree.setSearch(search);
			result=dstree;
			break;
		}
		case Const.FORM_INPUT_TYPE_LAZY_LIST:{
			LazyListFormCell lazylist=new LazyListFormCell();
			lazylist.setInputType(inputType);
			lazylist.setValue(value);
			lazylist.setRaw(raw);
			lazylist.setCode(code);
			lazylist.setAllowBlank(allowBlank);
			lazylist.setDisabled(disabled);
			lazylist.setReadOnly(readOnly);
			boolean multi=node.has("multi")?((BooleanNode) node.get("multi")).getBooleanValue():false;
			String dataset=node.get("dataset").asText();
			int search=node.has("search")?((Integer) ((IntNode) node.get("search")).getNumberValue()):4;
			lazylist.setMulti(multi);
			lazylist.setDataset(dataset);
			lazylist.setSearch(search);
			result=lazylist;
			break;
		}
		case Const.FORM_INPUT_TYPE_LAZY_TREE:{
			LazyTreeFormCell lazytree=new LazyTreeFormCell();
			lazytree.setInputType(inputType);
			lazytree.setValue(value);
			lazytree.setRaw(raw);
			lazytree.setCode(code);
			lazytree.setAllowBlank(allowBlank);
			lazytree.setDisabled(disabled);
			lazytree.setReadOnly(readOnly);
			boolean leaf=node.has("leaf")?((BooleanNode) node.get("leaf")).getBooleanValue():true;
			boolean multi=node.has("multi")?((BooleanNode) node.get("multi")).getBooleanValue():false;
			String dataset=node.get("dataset").asText();
			int search=node.has("search")?((Integer) ((IntNode) node.get("search")).getNumberValue()):4;
			lazytree.setLeaf(leaf);
			lazytree.setMulti(multi);
			lazytree.setDataset(dataset);
			lazytree.setSearch(search);
			result=lazytree;
			break;
		}
		case Const.FORM_INPUT_TYPE_PASSWORD:{
			PasswordFormCell password=new PasswordFormCell();
			password.setInputType(inputType);
			password.setValue(value);
			password.setRaw(raw);
			password.setCode(code);
			password.setAllowBlank(allowBlank);
			password.setDisabled(disabled);
			password.setReadOnly(readOnly);
			int minLength=node.has("minLength")?((Integer) ((IntNode) node.get("minLength")).getNumberValue()):0;
			int maxLength=node.has("maxLength")?((Integer) ((IntNode) node.get("maxLength")).getNumberValue()):Integer.MAX_VALUE;
			password.setMinLength(minLength);
			password.setMaxLength(maxLength);
			result=password;
			break;
		}
		case Const.FORM_INPUT_TYPE_CHECKBOX:{
			CheckBoxFormCell checkbox=new CheckBoxFormCell();
			checkbox.setInputType(inputType);
			checkbox.setValue(value);
			checkbox.setRaw(raw);
			checkbox.setCode(code);
			checkbox.setAllowBlank(allowBlank);
			checkbox.setDisabled(disabled);
			checkbox.setReadOnly(readOnly);
			String text=node.get("text").asText();
			String checked=node.has("checked")?node.get("checked").asText():"false";
			checkbox.setText(text);
			checkbox.setChecked(checked);
			result=checkbox;
			break;
		}
		default:
			throw new JsonParseException("inputType["+inputType+"]是无效的表单类型", null);
		}
		return result;
	}

}
